package game.task.keepAlive;

import com.google.protobuf.GeneratedMessage;
import dou.io.ByteArrayOutput;
import dou.scheduled.AbstractIntervalTask;
import game.ServerConfig;
import game.socket.RemoteClientSocket;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

import java.nio.ByteBuffer;

/**
 * 服务端心跳包发送任务
 * @author wizardc
 */
public class KeepAliveTask extends AbstractIntervalTask
{
    private static Logger logger = LogManager.getLogger("GameServer");

    private RemoteClientSocket _socket;

    // 是否接收到客户端的心跳
    private boolean _receivedClientKeepAlive;

    /**
     * 构造函数
     * @param socket 客户端套接字对象
     */
    public KeepAliveTask(RemoteClientSocket socket)
    {
        super(ServerConfig.getInstance().getKeepAliveTime(), ServerConfig.getInstance().getKeepAliveTime());
        _socket = socket;
        _receivedClientKeepAlive = true;
    }

    @Override
    public void run()
    {
        // 判断是否收到客户端的心跳
        if(_receivedClientKeepAlive)
        {
            _receivedClientKeepAlive = false;
        }
        else
        {
            // 没有收到则表示客户端断网
            _socket.lostConnection();
        }
    }

    /**
     * 编码一个消息对象为可用于发送的字节缓冲对象
     * @param protoID 协议 ID
     * @param msgID 消息 ID
     * @param message 消息对象
     * @throws Exception 消息处理错误时抛出该异常
     */
    private ByteBuffer encodeMessage(int protoID, int msgID, GeneratedMessage message) throws Exception
    {
        byte[] contentBytes = message.toByteArray();

        ByteArrayOutput dataOutput = new ByteArrayOutput();
        dataOutput.writeUnsignedInt(8 + contentBytes.length);
        dataOutput.writeInt(protoID);
        dataOutput.writeInt(msgID);
        dataOutput.writeBytes(contentBytes);

        return ByteBuffer.wrap(dataOutput.bytes());
    }

    /**
     * 接收到客户端的心跳包时调用
     */
    public void receiveClientKeepAlive()
    {
        _receivedClientKeepAlive = true;
    }
}
